package com.android.UrbanRemix;

/**
 * Sound Preview Manager. 
 * TODO Show soundURL and Address of the marker in the Title section.
 * @author BD
 */

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.location.Address;
import android.location.Geocoder;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;

public class SoundPreviewManagerTask extends
		AsyncTask<PreviewTaskInputPayload, Void, SoundPayloadforAsyncTask> {

	private static final String TAG = "Sound Preview Manager";

	ProgressDialog myPreviewProgressDialog;
	private MediaPlayer myPlayer;
	android.app.Dialog myPreviewDialog;
	private ImageButton play, pause, stop;
	Context mapContext;
	TextView addressview;

	public SoundPreviewManagerTask(Context context) {
		this.mapContext = context;
	}

	@Override
	protected void onPreExecute() {
		myPreviewProgressDialog = ProgressDialog.show(mapContext, "Loading",
				"Please wait...");

		myPreviewProgressDialog.setCancelable(true);

		// Cancel if download is taking too long. Go back to the map.
		myPreviewProgressDialog
				.setOnCancelListener(new DialogInterface.OnCancelListener() {
					public void onCancel(DialogInterface dialog) {
						Log.i("Async", "toDoInBackground Cancelled");
						SoundPreviewManagerTask.this.cancel(true);
					}
				});

		// Call dismiss from onPostExecute() after address download completes
		myPreviewProgressDialog
				.setOnDismissListener(new DialogInterface.OnDismissListener() {

					public void onDismiss(DialogInterface dialog) {
						// Do nothing.
						Log
								.i("PreviewTask",
										"Dismissed coz address could not be retreived.");
						// PreviewTask.this.cancel(true);
					}
				});
	}

	@Override
	protected SoundPayloadforAsyncTask doInBackground(
			PreviewTaskInputPayload... params) {

		// Perform a reverse Geo-coding operation to get the address.
		String markerAddress = reverseGeocode(params[0].getLatitude(),
				params[0].getLongitude());

		// Pack address and sound URL into SoundPayloadforAsyncTask.
		SoundPayloadforAsyncTask sendPayload = new SoundPayloadforAsyncTask(
				params[0].getURL(), markerAddress);

		return sendPayload;
	}

	private String reverseGeocode(int latitude, int longitude) {
		Geocoder myGC = new Geocoder(mapContext);
		String line1 = null, line2 = null, line3 = null;

		try {
			List<Address> addresses = new ArrayList<Address>();
			addresses = myGC
					.getFromLocation(latitude / 1E6, longitude / 1E6, 1);

			line1 = addresses.get(0).getAddressLine(0);
			line2 = addresses.get(0).getAddressLine(1);
			line3 = addresses.get(0).getAddressLine(2);

			String output = new String();
			if (line1 != null)
				output = output.concat(line1);
			if (line2 != null)
				output = output.concat(" " + line2);
			if (line3 != null)
				output = output.concat(" " + line3);
			return output;

		} catch (IOException e) {
			Log.i(TAG, "Problem with address retrieval");
			return null;
		}

	}

	/**
	 * This method posts the PreviewDialog onto the UI after address retrieval.
	 */
	protected void onPostExecute(SoundPayloadforAsyncTask payload) {
		myPreviewProgressDialog.dismiss();
		myPreviewDialog = new android.app.Dialog(mapContext);
		myPreviewDialog.setContentView(R.layout.sound_preview_dialog);
		myPreviewDialog.setTitle("		Sound Marker Preview");
		addressview = (TextView) myPreviewDialog.findViewById(R.id.addresstext);
		if (payload.getAddress() != null)
			addressview.setText(payload.getAddress());
		else
			addressview.setText("No Address available");

		try {
			myPlayer = new MediaPlayer();
			myPlayer.reset();
			myPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
			String sndurl = payload.getSoundURL().toString();
			sndurl = sndurl.replace(".wav", ".mp3");
			myPlayer.setDataSource(sndurl);
			myPlayer.prepareAsync();
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IllegalArgumentException e2) {
			e2.printStackTrace();
		} catch (IllegalStateException e3) {
			e3.printStackTrace();
		} catch (IOException e4) {
			e4.printStackTrace();
		}

		ImageButton close = (ImageButton) myPreviewDialog
				.findViewById(R.id.close);

		close.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				myPreviewDialog.dismiss();
			}
		});

		play = (ImageButton) myPreviewDialog.findViewById(R.id.play);
		pause = (ImageButton) myPreviewDialog.findViewById(R.id.pause);
		stop = (ImageButton) myPreviewDialog.findViewById(R.id.stop);

		play.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				myPlayer.start();
				play.setEnabled(false);
				pause.setEnabled(true);
				stop.setEnabled(true);
			}
		});

		pause.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				myPlayer.pause();
				play.setEnabled(true);
				pause.setEnabled(false);
				stop.setEnabled(false);
			}
		});

		stop.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				myPlayer.stop();
				myPlayer.prepareAsync();
				play.setEnabled(true);
				pause.setEnabled(false);
				stop.setEnabled(false);
			}
		});

		myPreviewDialog.show();

		// setup initial button statuses here
		play.setEnabled(true);
		pause.setEnabled(false);
		stop.setEnabled(false);

		// If media-player completes on its own
		myPlayer.setOnCompletionListener(new OnCompletionListener() {
			public void onCompletion(MediaPlayer mp) {
				play.setEnabled(true);
				pause.setEnabled(false);
				stop.setEnabled(false);
			}
		});

		// An error listener to reset MediaPlayer
		myPlayer.setOnErrorListener(new OnErrorListener() {
			public boolean onError(MediaPlayer mp, int what, int extra) {
				myPlayer.reset();
				play.setEnabled(true);
				pause.setEnabled(false);
				stop.setEnabled(false);
				return true;
			}
		});

		myPreviewDialog.setOnCancelListener(new OnCancelListener() {
			public void onCancel(DialogInterface dialog) {
				if (myPlayer.isPlaying())
					myPlayer.stop();
				myPlayer.release();
			}
		});

		myPreviewDialog
				.setOnDismissListener(new DialogInterface.OnDismissListener() {
					public void onDismiss(DialogInterface dialog) {
						if (myPlayer.isPlaying())
							myPlayer.stop();
						myPlayer.release();
					}
				});

	}

}
